/*
 *  Brno University of Technology
 *
 *  Copyright (C) 2009-2010 by Brno University of Technology and the contributors
 *
 *  Complete list of developers available at our web site:
 *
 *       http://spl.utko.feec.vutbr.cz
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/.
 */
package cz.vutbr.feec.utko.ef.evolution;

import org.apache.log4j.Logger;

import cz.vutbr.feec.utko.ef.core.Config;
import cz.vutbr.feec.utko.ef.evolution.stats.DefaultCrossoverAndMutationRateManager;
import cz.vutbr.feec.utko.ef.ga.GAGaussChromozome;
import cz.vutbr.feec.utko.ef.ga.GAOnePointChromozome;
import cz.vutbr.feec.utko.ef.ga.GAUniformChromozome;

/**
 * The Class DefaultEvolutionSpecifierGa is evolution defined for Genetic
 * Algorithms. The template can be chromozome with uniform crossover
 * (GAUniformChromozome) and chromozome with one-point crossover
 * (GAOnePointChromozome).
 */
public class DefaultEvolutionSpecifierGa extends DefaultEvolutionSpecifier {

	/** The template. */
	private Chromozome template;

	/** The log. */
	private static Logger log = Logger
			.getLogger(DefaultEvolutionSpecifierGa.class);

	/**
	 * Instantiates a new default evolution specifier ga.
	 * 
	 * @param cfg the cfg
	 * @param chromozome the chromozome
	 * @param eval the eval
	 */
	public DefaultEvolutionSpecifierGa(Config cfg, GAUniformChromozome chromozome,
			IFitnessEvaluator eval) {
		super(cfg, eval, new DefaultCrossoverAndMutationRateManager(cfg));
		template = chromozome;
	}
	
	/**
	 * Instantiates a new default evolution specifier ga.
	 * 
	 * @param cfg the cfg
	 * @param chromozome the chromozome
	 * @param eval the eval
	 */
	public DefaultEvolutionSpecifierGa(Config cfg, GAGaussChromozome chromozome,
			IFitnessEvaluator eval) {
		super(cfg, eval, new DefaultCrossoverAndMutationRateManager(cfg));
		template = chromozome;
	}
	
	/**
	 * Instantiates a new default evolution specifier ga.
	 * 
	 * @param cfg the cfg
	 * @param chromozome the chromozome
	 * @param eval the eval
	 * @param dcmrm the dcmrm
	 */
	public DefaultEvolutionSpecifierGa(Config cfg, GAUniformChromozome chromozome,
			IFitnessEvaluator eval, DefaultCrossoverAndMutationRateManager dcmrm) {
		super(cfg, eval, dcmrm);
		template = chromozome;
	}

	/* (non-Javadoc)
	 * @see cz.vutbr.feec.utko.ef.evolution.DefaultEvolutionSpecifier#createNewChromozome(cz.vutbr.feec.utko.ef.core.Config)
	 */
	@Override
	public Chromozome createNewChromozome(Config config) {
		if (template instanceof GAUniformChromozome) {
			log.debug("Creating new GAUniformChromozome chromozome.");
			return new GAUniformChromozome((GAUniformChromozome) template);
		} else if (template instanceof GAOnePointChromozome) {
			log.debug("Creating new GAOnePointChromozome chromozome.");
			return new GAOnePointChromozome((GAOnePointChromozome) template);
		} else if (template instanceof GAGaussChromozome) {
			log.debug("Creating new GAGaussChromozome chromozome.");
			return new GAGaussChromozome((GAGaussChromozome) template);
		} else {
			log.error("Invaid chromozome template type provided.");
			throw new RuntimeException(
					"Invalid template chromozome type provided. Only GAUniformChromozome "
							+ "or GAOnePointChromozome or GAGaussChromozome are allowed. ");
		}
	}

}
